package com.ruoyi.rsikManage.controller;

/**
 * @author wxx
 * @description
 * @date 2023/9/7 16:47

 */

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.rsikManage.AlarmTypeDic.domain.TAlarmTypeDicRequest;
import com.ruoyi.rsikManage.MonitorPoint.domain.TMonitorPointRequest;
import com.ruoyi.rsikManage.domain.AlarmEvent;
import com.ruoyi.rsikManage.domain.AlarmEventRequest;
import com.ruoyi.rsikManage.domain.common.StatisticsRequest;
import com.ruoyi.rsikManage.domain.vo.AlarmsVo;
import com.ruoyi.rsikManage.mapper.StatisticalAnalysisMapper;
import com.ruoyi.rsikManage.service.StatisticalAnalysisService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wxx
 * @description
 * @date 2023/8/9 16:56
 *
 *
 */
@RequestMapping("/Analysis")
@RestController
public class StatisticalAnalysisController extends BaseController {

    @Autowired
    private StatisticalAnalysisService statisticalAnalysisService;

    @Autowired
    private StatisticalAnalysisMapper statisticalAnalysisMapper;

    @Autowired
    private TokenService tokenService;


    @Value("${jy.switch}")
    private String JY_SWITCH;

    @Value("${jy.test}")
    private String JY_TEST;

    @Value("${jy.start_date}")
    private String Start_Date;

    @Value("${jy.name_prefix}")
    private String namePrefix;
    @Value("${jy.name_suffix}")
    private String nameSuffix;

    /**
     *  报警列表 算法名称字典接口
     */

    @GetMapping("/Alarm/algoName")
    public TableDataInfo selectAlarmAlgoName()
    {

        List<AlarmEvent> list = statisticalAnalysisService.selectAlarmAlgoName();
        return getDataTable(list);

    }

    /**
     *  获取报警列表-告警类型名称-下拉框数据
     */

    @PostMapping("/Alarm/algoName/group")
    public TableDataInfo selectAlarmAlgoNameGroup(HttpServletRequest httpServletRequest,
                                                  @RequestBody(required = false) AlarmEventRequest alarmEventRequest)
    {
        // 初始化单位代码列表
        List<Long> unitCodes = new ArrayList<>();
        // 如果请求体不为空，则从请求体中获取单位代码
        if (alarmEventRequest != null) {
            unitCodes = alarmEventRequest.getUnitCodes();
        }

        // 如果单位代码列表为空，则尝试从当前登录用户获取单位代码
        if (CollectionUtils.isEmpty(unitCodes)) {
            if (httpServletRequest != null && tokenService.getTokenInfo(httpServletRequest) != null) {
                unitCodes = tokenService.getLoginUserUnitCodes(httpServletRequest);
            }
        }

        // 设置最终确定的单位代码到请求参数中
        if (alarmEventRequest == null) {
            alarmEventRequest = new AlarmEventRequest();
        }
        List<AlarmEvent> list = statisticalAnalysisService.selectAlarmAlgoNameGroup(alarmEventRequest);
        // 将 List<AlarmEvent> 转换为 List<Map<String, String>>
        List<Map<String, String>> alarmTypeMaps = list.stream()
                .map(event -> {
                    Map<String, String> map = new LinkedHashMap<>();
                    map.put("alarmTypeName", event.getAlarmTypeName());
                    return map;
                })
                .collect(Collectors.toList());


        // 将 List<AlarmEvent> 转换为 List<String>
        List<String> alarmTypeNames = list.stream()
                .map(AlarmEvent::getAlarmTypeName) // 提取 alarmTypeName
                .distinct() // 确保 alarmTypeName 是唯一的（如果需要）
                .collect(Collectors.toList());
        return getDataTable(alarmTypeNames);

    }

    /**
     *  报警列表 组织名称 (煤矿名称的筛选)
     */

    @GetMapping("/Alarm/orgName")
    public TableDataInfo selectAlarmOrgName()
    {

        List<AlarmEvent> list = statisticalAnalysisService.selectAlarmOrgName();
        return getDataTable(list);

    }

    /**
     *  报警列表 监控点名称筛选
     */

    @PostMapping("/Alarm/apeName")
    public TableDataInfo selectAlarmApeName(@RequestBody AlarmEventRequest alarmEventRequest)
    {

        List<AlarmEvent> list = statisticalAnalysisService.selectAlarmApeName(alarmEventRequest);
        return getDataTable(list);

    }

    /**
     * 查询报警列表
     */
    //@PreAuthorize("@ss.hasPermi('rsikManage:electricParameter:list')")
    @PostMapping("/Alarm/list/V3")
    public TableDataInfo selectAllAlarmAllInfo(@RequestBody AlarmEventRequest alarmEventRequest) {
        // 用到多个列表筛选结果集 这里采用手动分页
        int pageSize = alarmEventRequest.getPageSize();
        int pageNum = alarmEventRequest.getPageNum();

        // 获取开始时间戳
        long startTime = System.currentTimeMillis();

        List<AlarmEvent> AllAlarmmaps = statisticalAnalysisService.selectAllAlarmInfo(alarmEventRequest);

        int startIndex = (pageNum - 1) * pageSize;

        int endIndex = Math.min(startIndex + pageSize, AllAlarmmaps.size());
        if(pageSize>AllAlarmmaps.size()){
            startIndex=0;
        }
        List<AlarmEvent> alarmEvents = AllAlarmmaps.subList(startIndex, endIndex);
        List<Long> urlList = new ArrayList<>();
        for (AlarmEvent event : alarmEvents) {
            urlList.add(event.getIdId());
        }

        if(urlList.size()==0){
            urlList.add(-1L);
        }

        alarmEventRequest.setIds(urlList);
        alarmEventRequest.setSort("DESC");

        List<AlarmEvent> alarmEvents1 = statisticalAnalysisMapper.selectAllAlarmInfoBase64(alarmEventRequest);

        //

        TableDataInfo dataTable = getDataTable(alarmEvents);
        dataTable.setTotal(AllAlarmmaps.size());

        // 获取结束时间戳
        long endTime = System.currentTimeMillis();
        //
        // 打印查询时间
        long queryTime = endTime - startTime;
        System.out.println("查询时间：" + queryTime + "毫秒");

        return dataTable;
    }

    /**
     * 获取告警列表
     *
     * orgName {string|null} 硬盘录像机名称，可选参数，默认为null
     * deviceName {string|null} 监控点名称，可选参数，默认为null
     * apeIds {List|null} 监控点名称数组，可选参数，默认为null
     * orgNames {string|null} 硬盘录像机名称，可选参数，默认为null
     * alarmTypeNames {List|null} 报警类型名称数组，可选参数，默认为null
     * alarmTypeName {string|null} 报警类型名称，可选参数，默认为null
     * startTime {string} 开始时间，格式为 "YYYY-MM-DD HH:mm:ss"
     *
     * endTime {string} 结束时间，格式为 "YYYY-MM-DD HH:mm:ss"
     * alarmLevel {string|null} 报警级别，可选参数，默认为null
     * handelStatus {string|null} 处理状态，可选参数，默认为null 1-未处置 2-处置中 3-已处置
     * filter {string} 报备状态，可选参数，默认为null 0-未报备 1-已报备
     * approve {string} 审批状态，可选参数，默认为null 1-正报 2-误报
     * pageNum {number} 页码，必填参数
     * pageSize {number} 每页记录数，必填参数
     *
     * @returns {object} 返回告警列表的结果
     */
    //@PreAuthorize("@ss.hasPermi('rsikManage:electricParameter:list')")
    @PostMapping("/Alarm/list")
    public TableDataInfo selectAllAlarmAllInfoV2(@RequestBody AlarmEventRequest alarmEventRequest,
                                                 HttpServletRequest httpServletRequest)
    {
        List<Long> unitCodes = alarmEventRequest.getUnitCodes();

    // 如果 unitCodes 为空或为空列表，则尝试从登录用户信息中获取
        if (unitCodes == null || unitCodes.isEmpty()) {
            if (httpServletRequest != null) {
                String tokenInfo = tokenService.getTokenInfo(httpServletRequest);
                if (tokenInfo != null) {
                    unitCodes = tokenService.getLoginUserUnitCodes(httpServletRequest);
                }
            }
        }

        // 设置最终确定的 unitCodes 到请求对象
        if (unitCodes != null && !unitCodes.isEmpty()) {
            alarmEventRequest.setUnitCodes(unitCodes);
        }

        // 调用服务层方法，获取告警列表
        List<AlarmEvent> allAlarmMaps = statisticalAnalysisService.selectAllAlarmInfoV2(alarmEventRequest);

        // 将告警列表封装为 TableDataInfo 对象
        TableDataInfo dataTable = getDataTable(allAlarmMaps);

        // 返回告警列表数据
        return dataTable;
    }

    /**
     * 获取告警列表 对外提供
     *
     * orgName {string|null} 硬盘录像机名称，可选参数，默认为null
     * deviceName {string|null} 监控点名称，可选参数，默认为null
     * apeIds {List|null} 监控点名称数组，可选参数，默认为null
     * orgNames {string|null} 硬盘录像机名称，可选参数，默认为null
     * alarmTypeNames {List|null} 报警类型名称数组，可选参数，默认为null
     * alarmTypeName {string|null} 报警类型名称，可选参数，默认为null
     * startTime {string} 开始时间，格式为 "YYYY-MM-DD HH:mm:ss"
     *
     * endTime {string} 结束时间，格式为 "YYYY-MM-DD HH:mm:ss"
     * alarmLevel {string|null} 报警级别，可选参数，默认为null
     * handelStatus {string|null} 处理状态，可选参数，默认为null 1-未处置 2-处置中 3-已处置
     * filter {string} 报备状态，可选参数，默认为null 0-未报备 1-已报备
     * approve {string} 审批状态，可选参数，默认为null 1-正报 2-误报
     * pageNum {number} 页码，必填参数
     * pageSize {number} 每页记录数，必填参数
     *
     * @returns {object} 返回告警列表的结果
     */
    //@PreAuthorize("@ss.hasPermi('rsikManage:electricParameter:list')")
    @PostMapping("/v1/api/alarms")
    public TableDataInfo getFilteredAlarms(@RequestBody AlarmEventRequest alarmEventRequest)
    {


        // 调用服务层方法，获取告警列表
        List<AlarmsVo> allAlarmMaps = statisticalAnalysisService.selectAlarms(alarmEventRequest);

        // 将告警列表封装为 TableDataInfo 对象
        TableDataInfo dataTable = getDataTable(allAlarmMaps);

        // 返回告警列表数据
        return dataTable;
    }


    //@PreAuthorize("@ss.hasPermi('rsikManage:electricParameter:list')")
    @PostMapping("/Alarm/list22")
    public String selectAllAlarmAllInfoV22(@RequestBody AlarmEventRequest alarmEventRequest) {

        String a= "{\n" +
                "\"total\": 15,\n" +
                "\"rows\": [\n" +
                "{\n" +
                "\"idId\": 4405,\n" +
                "\"unitCode\": null,\n" +
                "\"alarmLevel\": \"5\",\n" +
                "\"alarmTime\": \"2024-06-12 05:42:05\",\n" +
                "\"alarmTypeName\": \"头肩入侵危险区域\",\n" +
                "\"deviceName\": \"二采区变电所03\",\n" +
                "\"id\": null,\n" +
                "\"orgName\": \"井下视频\",\n" +
                "\"handleTime\": null,\n" +
                "\"httpUrl\":\"http://114.116.48.77:9001/var/car_image/ai/fxqyqtj20240312_054204.jpg}\n" +
                "],\n" +
                "\"code\": 200,\n" +
                "\"msg\": \"查询成功\"\n" +
                "}";

        return a;
    }

    @PostMapping("/Alarm/listp")
    public String selectAllAlarmAllInfolistp(@RequestBody AlarmEventRequest alarmEventRequest) {

        String a= " {\n" +
                "        \"total\": 15,\n" +
                "            \"rows\": [\n" +
                "        {\n" +
                "            \"id\": 4405,\n" +
                "                \"personId\": 1,\n" +
                "                \"personName\": \"刘明\",\n" +
                "                \"enterTime\": \"2024-06-12 05:42:05\",\n" +
                "                \"deviceName\": \"二采区变电所03\",\n" +
                "],\n" +
                "            \"code\": 200,\n" +
                "                \"msg\": \"查询成功\"\n" +
                "        }";

        return a;
    }


    @PostMapping("/Alarm/liste")
    public String selectAllAlarmAllInfoliste(@RequestBody AlarmEventRequest alarmEventRequest) {

        String a= "{ \n" +
                "\"total\": 15,\n" +
                "\"rows\": [\n" +
                "{\n" +
                "\"id\": 4405,\n" +
                "\"deviceId\": 1,\n" +
                "\"官网下载地址：https://www.navicat.com.cn/products#navicat-premium-lite\ndeviceName\": \"主运输机\",\n" +
                "\"alarmTime\": \"2024-06-12 05:42:05\",\n" +
                "\"alarmTypeName\": \"电流过高\",\n" +
                "\"alarmValue\": \"50A\"\n" +
                "],\n" +
                "\"code\": 200,\n" +
                "\"msg\": \"查询成功\"\n" +
                "}";

        return a;
    }



    @PostMapping("/EF/Alarm/list")
    public TableDataInfo selectAllAlarmAllInfoEf(@RequestBody AlarmEventRequest alarmEventRequest) {

        List<AlarmEvent> AllAlarmmaps = statisticalAnalysisService.selectAllAlarmInfoEF(alarmEventRequest);

        TableDataInfo dataTable = getDataTable(AllAlarmmaps);

        return dataTable;
    }



    @PostMapping("/Alarm/idId")
    public TableDataInfo selectAllAlarmAllById(@RequestBody AlarmEventRequest alarmEventRequest)
    {
//      startPage();
        List<AlarmEvent> list = statisticalAnalysisService.selectAlarmById(alarmEventRequest);
        return getDataTable(list);

    }


    @PutMapping("/Alarm/update")
    public AjaxResult updateAlarmInfo(@RequestBody AlarmEvent alarmEvent)
    {
//      startPage();
        int row = statisticalAnalysisService.updateAlarmInfo(alarmEvent);

        if(row>0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }

    }

    /**
     * 批量处置
     * @param alarmEvents
     * @return
     */

    @RequestMapping(value = "/Alarm/batchUpdate", method = {RequestMethod.GET, RequestMethod.POST})
    public AjaxResult batchUpdateAlarmInfo(@RequestBody List<AlarmEvent> alarmEvents)
    {
//      startPage();
        int row = statisticalAnalysisService.batchUpdateAlarmInfo(alarmEvents);

        if(row>0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }

    }
//


    @GetMapping("/index/list/v2")
    public Map<String,Object> selectIndex(AlarmEventRequest alarmEventRequest,HttpServletRequest httpServletRequest)

    {
        LocalDate today = LocalDate.now();
        String todayString = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        if("true".equals(JY_TEST)){
            todayString=Start_Date;
            alarmEventRequest.setStartTime(todayString + " 00:00:00");
        }
        alarmEventRequest.setStartTime(todayString + " 00:00:00");
        alarmEventRequest.setEndTime(todayString + " 23:59:59");

        // 获取当前登录用户的单位代码
        List<Long> unitcodes = tokenService.getLoginUserUnitCodes(httpServletRequest);
        alarmEventRequest.setUnitCodes(unitcodes);

        Map<String, Object> result = statisticalAnalysisService.selectAlarmIndex(alarmEventRequest);

        return result;

    }

    /**
     * 时间 24/10/29
     * @param statisticsRequest
     * @param httpServletRequest
     * @return
     */
    @GetMapping("/index/list")
    public Map<String,Object> selectIndexForUnitCodes(StatisticsRequest statisticsRequest, HttpServletRequest httpServletRequest)

    {
        Long unitCode = statisticsRequest.getUnitCode();
        AlarmEventRequest alarmEventRequest = new AlarmEventRequest();
        if (unitCode == null ){
            unitCode = tokenService.getLoginUserUnitCode(httpServletRequest);
        }

        alarmEventRequest.setUnitCode(unitCode);
        LocalDate today = LocalDate.now();
        LocalDateTime startDateTime;
        LocalDateTime endDateTime;

        if ("true".equals(JY_TEST)) {
            startDateTime = LocalDateTime.parse(Start_Date + "T00:00:00");
        } else {
            startDateTime = today.atStartOfDay(); // 获取当天的开始时间
        }

        endDateTime = today.atTime(23, 59, 59); // 获取当天的结束时间

        alarmEventRequest.setStartTime(startDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        alarmEventRequest.setEndTime(endDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        Map<String, Object> result = statisticalAnalysisService.selectAlarmIndexForUnitCodes(alarmEventRequest);

        return result;

    }

    @GetMapping("/index/list/demo")
    public Map<String,Object> selectIndexDemo(AlarmEventRequest alarmEventRequest)
    {
        LocalDate today = LocalDate.now();
        String todayString = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        alarmEventRequest.setStartTime("2023-09-07" + " 00:00:00");
        alarmEventRequest.setEndTime("2023-09-07" + " 23:59:59");

        Map<String, Object> result = statisticalAnalysisService.selectAlarmIndexDemo(alarmEventRequest);

        return result;

    }

    @GetMapping("/mt/list")
    public List<String >mtlist (String apeName)
    {
        LocalDate today = LocalDate.now();

        List<String > result = statisticalAnalysisService.mtlist(apeName);

        return result;

    }



    /**
     * 综合门户首页
     */
    @GetMapping("/display/index/list")
    public Map<String,Object> selectDisplayIndex(AlarmEventRequest alarmEventRequest)

    {
        LocalDate today = LocalDate.now();
        String todayString = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        if("true".equals(JY_SWITCH)){

        }else {
            todayString=Start_Date;
        }

        alarmEventRequest.setStartTime(todayString + " 00:00:00");
        alarmEventRequest.setEndTime(todayString + " 23:59:59");

        Map<String, Object> result = statisticalAnalysisService.selectDisplayIndex(alarmEventRequest);

        return result;

    }

    //接收报警数据
    @RequestMapping(value = "/getdata", method = {RequestMethod.GET, RequestMethod.POST})
    public AjaxResult InboundDataOftAlarm(@RequestBody(required = false) Map map) {

        int row = statisticalAnalysisService.InboundDataOftAlarm(map);

        if (row>0){
            return AjaxResult.success("入库成功");
        }else {
            return AjaxResult.error("入库失败");

        }
        // 入库数据

    }

    @RequestMapping(value = "/{unitCode}/getData", method = {RequestMethod.GET, RequestMethod.POST})
    public AjaxResult InboundDataOftAlarmForUnitCodes(
            @RequestBody(required = false) Map map,
            @PathVariable Long unitCode) {

        // 将 unitCode 添加到 map 中，以便传递给服务层
        map.put("unitCode", unitCode);

        int row = statisticalAnalysisService.InboundDataOftAlarmForUnitCodes(map);

        if (row > 0) {
            return AjaxResult.success("入库成功");
        } else {
            return AjaxResult.error("入库失败");
        }
    }



    //接收报警数据
    @RequestMapping(value = "/getdata2", method = {RequestMethod.GET, RequestMethod.POST})
    public AjaxResult InboundDataOftAlarm2(@RequestBody(required = false) Map map) {

        String alarmTypeName = map.get("alarm_type_name").toString();
        HashMap<Object, Object> insertMap = new HashMap<>();

        boolean hasPrefix = alarmTypeName.contains(namePrefix);
        boolean hasSuffix = alarmTypeName.contains(nameSuffix);

        if (hasPrefix && hasSuffix) {
            // 如果前缀和后缀都存在，则先截取前缀，再截取后缀
            int underscoreIndex = alarmTypeName.indexOf(namePrefix);
            if (underscoreIndex != -1) {
                alarmTypeName = alarmTypeName.substring(underscoreIndex + namePrefix.length());
                int endscoreIndex = alarmTypeName.indexOf(nameSuffix);
                if (endscoreIndex != -1) {
                    alarmTypeName = alarmTypeName.substring(0, endscoreIndex);
                }
            }
        } else if (hasPrefix) {
            // 如果只有前缀存在，则截取前缀后的字符串
            int underscoreIndex = alarmTypeName.indexOf(namePrefix);
            if (underscoreIndex != -1) {
                alarmTypeName = alarmTypeName.substring(underscoreIndex + namePrefix.length());
            }
        } else if (hasSuffix) {
            // 如果只有后缀存在，则截取后缀前的字符串
            int endscoreIndex = alarmTypeName.indexOf(nameSuffix);
            if (endscoreIndex != -1) {
                alarmTypeName = alarmTypeName.substring(0, endscoreIndex);
            }
        }

        insertMap.put("alarmTypeName", alarmTypeName);




        return AjaxResult.success(insertMap);
    }



    @RequestMapping(value = "/getdata/V2", method = {RequestMethod.GET, RequestMethod.POST})
    public AjaxResult InboundDataOftAlarmV2(@RequestBody(required = false) Map map) {

        int row = statisticalAnalysisService.InboundDataOftAlarmV2(map);

        if (row>0){
            return AjaxResult.success("转换成功");
        }else {
            return AjaxResult.error("转化失败");

        }


        // 入库数据

    }
    ////地点/时间/图片/描述/上传者/描述/类型
    @PostMapping("/upload")
    public String uploadFile(@RequestPart("file") MultipartFile file, @RequestParam("type") String type) {
        if (file.isEmpty()) {
            return "请选择要上传的文件";
        }

        try {
            // 获取文件的原始名称
            String originalFileName = file.getOriginalFilename();
            String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
            UUID uuid = UUID.randomUUID();
            String fileName = uuid.toString() + fileExtension;
            String storagePath = "";

            if (type.equals("image")) {
                storagePath = "D:/zdzh/var/image/";
            } else {
                storagePath = "D:/zdzh/var/video/";
            }

            // 指定存储目录

            // 创建目标文件对象
            File destFile = new File(storagePath + fileName);

            // 检查目标目录是否存在，不存在则创建
            File destDirectory = destFile.getParentFile();
            if (!destDirectory.exists()) {
                destDirectory.mkdirs();
            }

            // 将文件保存到目标位置
            FileOutputStream fos = new FileOutputStream(destFile);
            fos.write(file.getBytes());
            fos.close();

            return "文件上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败";
        }
    }


    @PostMapping("/upload/image")
    public String uploadFile(@RequestPart("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "请选择要上传的文件";
        }

        try {
            // 获取文件的原始名称
            UUID uuid = UUID.randomUUID();
            String fileName = uuid.toString();
            String storagePath = "";
            storagePath = "D:/zdzh/Image/";


            // 指定存储目录

            // 创建目标文件对象
            File destFile = new File(storagePath + fileName);

            // 检查目标目录是否存在，不存在则创建
            File destDirectory = destFile.getParentFile();
            if (!destDirectory.exists()) {
                destDirectory.mkdirs();
            }

            // 将文件保存到目标位置
            FileOutputStream fos = new FileOutputStream(destFile);
            fos.write(file.getBytes());
            fos.close();

            return "文件上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败";
        }
    }

}
